<template>
  <div>
    <el-container>
      <el-aside width="300px" style="height: calc(100vh - 160px)">
        <div class="tools">
          <el-input
            placeholder="输入关键字进行过滤"
            v-model="filterText">
          </el-input>
          <div class="btns-tools is-fixed">
            <div class="group">
              <el-button icon="el-icon-circle-plus-outline" :disabled="disabled" @click="handlerFunc('add')" size="mini">新增</el-button>
              <el-button icon="el-icon-edit-outline" @click="handlerFunc('edit')" size="mini">修改</el-button>
              <el-button icon="el-icon-delete" @click="handlerFunc('delete')" size="mini">{{isShow ? '删除' : '批量删除'}}</el-button>
            </div>
          </div>
        </div>
        <div class="menu-bar">
          <el-tree
            class="filter-tree"
            :data="menus"
            :props="defaultProps"
            :filter-node-method="filterNode"
            @check-change="handleCheckChange"
            node-key="catId"
            :default-expanded-keys="expandKey"
            :default-checked-keys="selected"
            show-checkbox
            :draggable="true"
            :check-strictly="true"
            ref="tree"
            :allow-drop="allowDrop"
            @node-drop="handleDrop"
            :highlight-current="true">
            <!-- el-tree 的属性 -->
            <!-- :data="menus" 数据源 -->
            <!-- :props="defaultProps" 展示配置 -->
            <!-- :load="loadNode" lazy 都是懒加载配置缓冲 -->
            <!-- :filter-node-method="filterNode" 搜索框 -->
            <!-- default-expand-all -->
            <!-- :expand-on-click-node="false" 为false的时候只有点击小箭头才展示子节点 -->
            <!-- :default-expanded-keys="expandKey" 默认展示这个 id 所在的分组 -->
            <!-- 唯一标识 node-key="catId"-->
            <!--
              :allow-drop="allowDrop" 拖拽时判定目标节点能否被放置。type 参数有三种情况：
              'prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
            -->
            <!-- @node-drop="handleDrop" 节点被拖拽成功之后触发 -->
            <!-- :allow-drag="allowDrag" 判断节点能否被拖拽 -->
            <!-- :check-strictly="true" 在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false -->
            <!-- :draggable="true" 设置节点可拖拽 -->
            <!--<span class="custom-tree-node" slot-scope="{ node, data }">-->
          </el-tree>
        </div>
      </el-aside>
      <el-main>
        <div class="filter-container">
          <!-- 按钮区域 -->
          <div class="btns-tools">
            <div class="groups">
              <el-button icon="el-icon-circle-plus-outline" @click="handlerChildren('add')">新建</el-button>
              <el-button icon="el-icon-edit-outline" @click="handlerChildren('edit')">修改</el-button>
              <el-button icon="el-icon-delete" @click="handlerChildren('delete')">删除</el-button>
              <el-button icon="el-icon-document" @click="handlerChildren('check')">查看</el-button>
            </div>
          </div>
          <el-card class="box-card cardHeight" style="height: calc(100vh - 170px)padding:0 10px">
            <!-- 搜索区域 -->
            <!--<div v-if="notice_btn_search" class="search-tools">
              <el-form :inline="true" class="demo-form-inline">
                <el-form-item label="查询内容">
                  <el-input v-model="listQuery.title" placeholder="请输入标题" />
                </el-form-item>
                <el-form-item>
                  <el-button class="search-tools-btns-primary" type="primary" @click="handleSearch()">查询</el-button>
                </el-form-item>
              </el-form>
            </div>-->
            <div class="block">
              <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="[100, 200, 300, 400]"
                :page-size="100"
                layout="total, sizes, prev, pager, next, jumper"
                :total="400">
              </el-pagination>
            </div>
          </el-card>
        </div>
      </el-main>
    </el-container>

    <!-- 对话框 -->
    <el-dialog
      id="eldialog"
      top="100px"
      style="text-align:left"
      :close-on-click-modal="false"
      :visible.sync="dialogVisible"
      width="1000px"
      :before-close="handleClose"
      :title="title"
      center
    >
      <el-form ref="form" :rules="rules" :model="category"  label-width="80px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="category.name"></el-input>
        </el-form-item>
        <el-form-item label="父分类id">
          <el-input :disabled="true" v-model="category.parentCid"></el-input>
        </el-form-item>
        <el-form-item label="层级">
          <el-input :disabled="true" v-model="category.catLevel"></el-input>
        </el-form-item>
        <el-form-item label="是否显示">
          <el-input v-model="category.showStatus"></el-input>
        </el-form-item>
        <el-form-item label="排序">
          <el-input v-model="category.sort"></el-input>
        </el-form-item>
        <el-form-item label="图标地址">
          <el-input v-model="category.icon"></el-input>
        </el-form-item>
        <el-form-item label="计量单位">
          <el-input v-model="category.productUnit"></el-input>
        </el-form-item>
        <el-form-item label="商品数量" prop="productCount">
          <el-input v-model="category.productCount"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button v-if="title.indexOf('新建') !== -1" type="primary" @click="submit('form')">确 定</el-button>
        <el-button v-if="title.indexOf('修改') !== -1" type="primary" @click="update('form')">更 新</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  export default {
    name: 'category',
    data () {
      return {
        isShow: true,
        count: 1,
        updateNode: [],
        maxLevel: 0,
        disabled: false,
        rules: {
          name: [
            { required: true, message: '请输入分类名称', trigger: 'blur' },
            { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
          ],
          productCount: [
            { required: true, message: '请输入数量', trigger: 'blur' },
            { min: 1, max: 5, message: '长度在 1 到 99999 之间', trigger: 'blur' }
          ]
        },
        currentPage: 1,
        category: {
          name: '',
          parentCid: 0,
          catLevel: 0,
          showStatus: 1,
          sort: 0,
          icon: '',
          productUnit: '',
          productCount: 0
        },
        dialogVisible: false,
        title: '',
        show: false,
        filterText: '',
        menus: [],
        selected: [],
        expandKey: [],
        defaultProps: {
          // 子节点的属性
          children: 'children',
          // 展示的属性
          label: 'name'
        }
      }
    },
    watch: {
      filterText (val) {
        this.$refs.tree.filter(val)
      },
      selected (selected) {
        if (selected.length > 1) {
          this.isShow = false
        } else {
          this.isShow = true
        }
      }
    },
    mounted () {
      this.getMenu()
    },
    methods: {
      // draggingNode 当前节点被放在 dropNode 的 type 位置
      allowDrop (draggingNode, dropNode, type) {
        // 自己的代码
        if (type === 'inner') {
          // 当前节点个数
          this.getNodeCount(draggingNode)
          let count = this.count
          this.count = 1
          this.getNodeCount(dropNode)
          let store = this.count
          this.count = 1
          return count < 3 && count <= store
        }
        return (3 - draggingNode.data.catLevel + 1) + ((3 - dropNode.data.catLevel + 1) % 3) < 4 || (3 - draggingNode.data.catLevel + 1) === (3 - dropNode.data.catLevel + 1)
      },
      // draggingNode 被拖动的节点 拖到了 dropNode 节点的 dropType 位置
      handleDrop (draggingNode, dropNode, dropType, ev) {
        // 设置被拖拽节点的 parentId
        let pId = 0
        let siblings = null
        let catLevel = 0
        if (dropType === 'before' || dropType === 'after') {
          pId = dropNode.data.parentCid
          siblings = dropNode.parent.childNodes
        } else {
          pId = dropNode.data.catId
          siblings = dropNode.childNodes
        }
        // 设置当前节点的最新顺序
        for (let i = 0; i < siblings.length; i++) {
          // 被拖拽的节点
          if (siblings[i].data.catId === draggingNode.data.catId) {
            // 修改当前被拖拽节点的层级
            catLevel = siblings[i].level
            this.updateLevel(siblings[i])
            this.updateNode.push({ catId: siblings[i].data.catId, sort: i, parentCid: pId, catLevel: catLevel })
          } else {
            this.updateNode.push({ catId: siblings[i].data.catId, sort: i })
          }
        }
        this.$http({
          url: this.$http.adornUrl('/product/category/update/batch'),
          method: 'post',
          data: this.$http.adornData(this.updateNode, false)
        }).then(response => {
          this.expandKey = [ pId ]
        })
      },
      getNodeCount (node) {
        if (node.childNodes.length > 0) {
          this.count++
          this.getNodeCount(node.childNodes[0])
        }
      },
      updateLevel (node) {
        if (node.childNodes.length > 0) {
          for (let i = 0; i < node.childNodes.length; i++) {
            var cNode = node.childNodes[i].data
            // 这里的 level 值是 elementui 提供的属性值
            this.updateNode.push({ catId: cNode.catId, catLevel: node.childNodes[i].level })
            this.updateLevel(node.childNodes[i])
          }
        }
      },
      // 统计当前几点
      countNodeLevel (node) {
        if (node.children !== null && node.children.length > 0) {
          for (let i = 0; i < node.children.length; i++) {
            if (node.children[i].catLevel > this.maxLevel) {
              this.maxLevel = node.children[i].catLevel
            }
            this.countNodeLevel(node.children[i])
          }
        }
      },
      update (formName) {
        var that = this
        that.$refs[formName].validate((valid) => {
          if (valid) {
            that.$http({
              url: that.$http.adornUrl('/product/category/update'),
              method: 'post',
              data: that.$http.adornData(that.category, false)
            }).then(response => {
              that.$message({
                message: '保存成功',
                type: 'success',
                duration: 1500
              })

              that.expandKey = [ that.selected[0].catId ]
              that.selected = []
              that.handleCloseData()
              that.getMenu()
              setTimeout(() => {
                that.dialogVisible = false
              }, 150)
            })
          } else {
            console.log('error submit!!')
            return false
          }
        })
      },
      submit (formName) {
        var that = this
        that.$refs[formName].validate((valid) => {
          if (valid) {
            that.$http({
              url: that.$http.adornUrl('/product/category/save'),
              method: 'post',
              data: that.$http.adornData(that.category, false)
            }).then(response => {
              that.$message({
                message: '保存成功',
                type: 'success',
                duration: 1500
              })
              if (that.selected.length !== 0) {
                that.expandKey = [ that.selected[0].catId ]
              }
              that.selected = []
              that.handleCloseData()
              that.getMenu()
              setTimeout(() => {
                that.dialogVisible = false
              }, 150)
            })
          } else {
            console.log('error submit!!')
            return false
          }
        })
      },
      handleCloseData () {
        this.category = {
          name: '',
          parentCid: 0,
          catLevel: 0,
          showStatus: 1,
          sort: 0,
          icon: '',
          productUnit: '',
          productCount: 0
        }
      },
      handleSizeChange (val) {
        console.log(`每页 ${val} 条`)
      },
      handleCurrentChange (val) {
        console.log(`当前页: ${val}`)
      },
      handleClose () {
        this.handleCloseData()
        if (this.selected.length !== 0) {
          this.expandKey = [ this.selected[0].parentCid ]
        }
        this.getMenu()
        setTimeout(() => {
          this.selected = []
          this.dialogVisible = false
        }, 200)
      },
      handlerFunc (info) {
        var that = this
        if (info === 'add') {
          if (that.selected.length > 1) {
            that.$message({
              type: 'info',
              message: '请选择一条记录进行操作!',
              duration: 1500
            })
            that.getMenu()
            // 保持展示不变
            this.expandKey = [that.selected[0].parentCid]
            that.selected = []
            return
          }
          if (that.selected.length === 0) {
            that.title = `当前在【根目录】节点下新建`
            that.category.parentCid = 0
            that.category.catLevel = 1
            that.dialogVisible = true
            return
          }
          that.title = `当前在【${that.selected[0].name}】节点下新建`
          that.category.parentCid = that.selected[0].catId
          that.category.catLevel = that.selected[0].catLevel * 1 + 1
          that.dialogVisible = true
        }
        if (info === 'edit') {
          if (that.selected.length === 0) {
            that.$message({
              type: 'info',
              message: '请选择一条记录进行操作!',
              duration: 1500
            })
            that.getMenu()
            return
          }
          if (that.selected.length > 1) {
            that.$message({
              type: 'info',
              message: '请选择一条记录进行操作!',
              duration: 1500
            })
            that.getMenu()
            // 保持展示不变
            that.expandKey = [that.selected[0].parentCid]
            that.selected = []
            return
          }
          that.$http({
            url: that.$http.adornUrl('/product/category/info/' + that.selected[0].catId),
            method: 'get'
          }).then(response => {
            that.title = `修改【${that.selected[0].name}】节点`
            that.category = response.data.category
          })
          that.dialogVisible = true
        }
        if (info === 'delete') {
          if (that.selected.length === 0) {
            that.$message({
              type: 'info',
              message: '请选择一条记录进行操作!',
              duration: 1500
            })
            that.getMenu()
            return
          }
          for (let i = 0; i < this.selected.length; i++) {
            if (that.selected[i].children !== undefined && that.selected[i].children !== null && that.selected[i].children.length > 0) {
              that.$message({
                type: 'info',
                message: '请先删除子节点!',
                duration: 1500
              })
              that.getMenu()
              // 保持展示不变
              that.expandKey = [that.selected[0].parentCid]
              that.selected = []
              return
            }
          }
          let ids = this.selected.map(item => item.catId)
          that.$confirm('是否删除【' + that.selected.length + '】条信息？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.$http({
              url: this.$http.adornUrl('/product/category/delete'),
              method: 'post',
              data: this.$http.adornData(ids, false)
            }).then(({ data }) => {
              this.$message({
                message: '删除成功',
                type: 'success',
                duration: 1500
              })
              // 刷新菜单
              this.getMenu()
              // 保持展示不变
              this.expandKey = [ that.selected[0].parentCid ]
              this.selected = []
            })
          }).catch(() => {
            that.$message({
              type: 'info',
              message: '已取消删除',
              duration: 1500
            })
            that.getMenu()
            // 保持展示不变
            this.expandKey = [ that.selected[0].parentCid ]
            that.selected = []
          })
        }
      },
      handleCheckChange (data, checked, indeterminate) {
        if (checked === true) {
          this.selected.push(data)
        }
      },
      handlerChildren (info) {
        console.log(info)
      },
      // 搜索
      filterNode (value, data) {
        if (!value) return true
        return data.name.indexOf(value) !== -1
      },
      getMenu () {
        this.$http({
          url: this.$http.adornUrl('/product/category/list/tree'),
          method: 'get'
        }).then(({ data }) => {
          this.menus = data.data
        })
      }
    },
    created () {
      // this.getMenu()
    }
  }
</script>

<style scoped>
  .tools .btns-tools {
    line-height: 50px;
    z-index: 1
  }
</style>
